﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using SilverLightApp.DataHelperService;
using System.Windows.Browser;


namespace SilverLightApp
{
  public partial class MainPage : UserControl
  {
    public string country = "NA";
    public int chosenYear = -1;
    public delegate void SetRectangle(object stat, double height);
    public DataHelperClient dataHelperClient = new DataHelperClient();
    public Int32 maxCount = 0;
    private App app = (App)Application.Current;
    HtmlDocument doc = null;
    public MainPage()
    {
      InitializeComponent();
      dataHelperClient.GetMaxValueCompleted += new EventHandler<GetMaxValueCompletedEventArgs>(dataHelperClient_GetMaxValueCompleted);
      dataHelperClient.GetTopCausesCompleted += new EventHandler<GetTopCausesCompletedEventArgs>(dataHelperClient_GetTopCausesCompleted);
      dataHelperClient.GetDataPointsCompleted += new EventHandler<GetDataPointsCompletedEventArgs>(dataHelperClient_GetDataPointsCompleted);
      doc = HtmlPage.Document;
      HtmlElement countryName = doc.GetElementById("countryName");
      country = countryName.GetAttribute("value");
      if (String.IsNullOrWhiteSpace(country))
      {
        MessageBox.Show("Please select a country first");
        return;
      }
      dataHelperClient.GetDataPointsAsync(country);
    }

    void dataHelperClient_GetDataPointsCompleted(object sender, GetDataPointsCompletedEventArgs e)
    {
      SetupSlider(e);
      dataHelperClient.GetMaxValueAsync(country);
    }

    private void SetupSlider(GetDataPointsCompletedEventArgs e)
    {
      yearPicker.Minimum = e.Result[0];
      yearPicker.Maximum = e.Result[e.Result.Count - 1];
      int mid = (e.Result.Count - 1) / 2;
      tbYearStart.Text = yearPicker.Minimum.ToString();
      tbYearMid.Text = e.Result[mid].ToString();
      tbYearEnd.Text = yearPicker.Maximum.ToString();
      tbChosenYear.Text = "Year: " + yearPicker.Minimum.ToString();
      doc = HtmlPage.Document;
      HtmlElement hidden = doc.GetElementById("sliderValue");
      hidden.SetAttribute("value", yearPicker.Minimum.ToString().Trim());
      chosenYear = (int)yearPicker.Minimum;
    }

    void dataHelperClient_GetMaxValueCompleted(object sender, GetMaxValueCompletedEventArgs e)
    {
      maxCount = e.Result;
      PopulateYAxis();
      System.Threading.Thread.Sleep(1000);
      dataHelperClient.GetTopCausesAsync(chosenYear.ToString(), country);
    }

    void dataHelperClient_GetTopCausesCompleted(object sender, GetTopCausesCompletedEventArgs e)
    {
      if (e.Error == null)
      {
        PopulateXAxis(e);
        UpdateGraph(e);
      }
      else
        MessageBox.Show("Could not fetch data from DataBase. Error: " + e.Error.Message, "Unexpected Error", MessageBoxButton.OK);
    }

    private void PopulateYAxis()
    {
      string elementName = "tbCount{0}";
      Int32 jump = maxCount / 5;
      int powerOf10 = (int)Math.Log10(maxCount) - 1;
      for (int i = 1; i <= 5; i++)
      {
        int multiplier = 0;
        TextBlock block = (TextBlock)LayoutRoot.FindName(String.Format(elementName, i));
        multiplier = (int)((jump * i) / Math.Pow(10, powerOf10));
        block.Text = (multiplier * Math.Pow(10, powerOf10)).ToString();
      }
    }

    private void PopulateXAxis(GetTopCausesCompletedEventArgs e)
    {
      string elementName = "tbCause{0}";
      for (int i = 0; i < e.Result.Count; i++)
      {
        TextBlock block = (TextBlock)LayoutRoot.FindName(String.Format(elementName, i + 1));
        block.Text = e.Result[i].Cause.Replace(", ICD10", "").Replace(", ICD9", "");
      }
    }

    private void UpdateGraph(GetTopCausesCompletedEventArgs e)
    {
      doc = HtmlPage.Document;
      HtmlElement hidden = doc.GetElementById("chosenCause");
      if (hidden.GetAttribute("value") == "NA")
      {
        hidden.SetAttribute("value", e.Result[0].Cause.Replace(", ICD10", "").Replace(", ICD9", "").Trim());
      }
      double factor = (double)360 / maxCount;
      string elementName = "rectStat{0}";
      for (int i = 0; i < e.Result.Count; i++)
      {
        double newHeight = new double();
        Rectangle bar = (Rectangle)LayoutRoot.FindName(String.Format(elementName, i + 1));
        newHeight = e.Result[i].Count * factor;
        double currHeight = bar.Height;
        {
          System.Threading.Thread updaterThread = new System.Threading.Thread(
            unused => UpdateStats(bar, currHeight, newHeight));
          updaterThread.Start();
        }
      }
    }

    public void UpdateStats(Rectangle bar, double currHeight, double newHeight)
    {
      SetRectangle setRectangle = new SetRectangle(UpdateStat);
      double step = 0;
      if (currHeight < newHeight)
      {
        while (currHeight < newHeight)
        {
          step = Math.Max((newHeight - currHeight) / 5, 3);
          currHeight = currHeight + step;
          this.Dispatcher.BeginInvoke(setRectangle, bar, currHeight);
          System.Threading.Thread.Sleep(50);
        }
      }
      else
      {
        while (currHeight > newHeight)
        {
          step = Math.Max((newHeight - currHeight) / 5, 3);
          currHeight = currHeight - step;
          this.Dispatcher.BeginInvoke(setRectangle, bar, currHeight);
          System.Threading.Thread.Sleep(50);
        }
      }
    }

    public void UpdateStat(object obj, double i)
    {
      Rectangle rect = (Rectangle)obj;
      if (i <= 0) return;
      rect.Height = i;
    }

    private string wrapText(string nonWrapedText)
    {
      if (nonWrapedText.Length <= 20) return nonWrapedText;
      string wrapedText = string.Empty;
      for (int i = 0; i < nonWrapedText.Length/20; i++)
      {
        int start = i*20;
        int count = Math.Min(20, nonWrapedText.Length-(i*20));
        wrapedText = wrapedText + nonWrapedText.Substring(start, count);
      }
      return wrapedText;
    }

    private void yearPicker_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
    {
      if (e.OldValue == 0.0) return;
      int newChosenYear = (int)((Slider)sender).Value;
      if (newChosenYear == chosenYear) return;
      chosenYear = newChosenYear;
      doc = HtmlPage.Document;
      HtmlElement hidden = doc.GetElementById("sliderValue");
      hidden.SetAttribute("value", chosenYear.ToString());
      tbChosenYear.Text = "Year: " + chosenYear.ToString();
      dataHelperClient.GetTopCausesAsync(chosenYear.ToString(), country);
    }

    private void tbCause1_MouseEnter(object sender, MouseEventArgs e)
    {
      TextBlock tb = (TextBlock) sender;
      tb.FontStyle = FontStyles.Italic;
      tb.Foreground = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0));
    }

    private void tbCause1_MouseLeave(object sender, MouseEventArgs e)
    {
      TextBlock tb = (TextBlock)sender;
      tb.FontStyle = FontStyles.Normal;
      tb.Foreground = new SolidColorBrush(Color.FromArgb(255, 0, 0, 0));
    }

    private void tbCause1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
      TextBlock tb = (TextBlock)sender;
      string cause = tb.Text.Trim();
      doc = HtmlPage.Document;
      HtmlElement hidden = doc.GetElementById("chosenCause");
      hidden.SetAttribute("value", cause);
    }
  }
}
